/*****************************************************************//**
 * \file   ReadMesh.h
 * \brief  ReadMesh
 *
 * \author Wyatt
 * \date   May 2023
 *********************************************************************/
#pragma once

#include <unordered_map>
#include <map>
#include <vector>

class AnsysToIBEBuilderModel;
class ReadMesh
{
public:
	ReadMesh();
	virtual ~ReadMesh();

	static ReadMesh* Inst();

	static std::vector<int>& GetNodeId()
	{
		return ReadMesh::Inst()->allNodeId;
	};

	static std::vector<double>& GetNodeCoor()
	{
		return ReadMesh::Inst()->allNodeCoor;
	};

	static int GetNodeCount()
	{
		return ReadMesh::Inst()->allNodeCoor.size() / 3;
	};

	static int GetCellCount()
	{
		return ReadMesh::Inst()->allElmentType.size();
	};

	static std::vector<int>& GetCellId()
	{
		return ReadMesh::Inst()->allElementId;
	};

	static std::vector<int>& GetCellNode()
	{
		return ReadMesh::Inst()->allElementNode;
	};

	static std::vector<int>& GetCellType()
	{
		return ReadMesh::Inst()->allElmentType;
	};

	static std::vector<int>& GetCellIndex()
	{
		return ReadMesh::Inst()->elementIndex;
	};

	static std::vector<std::string>& GetCellFormulation()
	{
		return ReadMesh::Inst()->elementFormulation;
	};

	static std::vector<std::string>& GetNodeSetName()
	{
		return ReadMesh::Inst()->allNodeSetName;
	};

	static std::vector<std::vector<int>>& GetNodeSet()
	{
		return ReadMesh::Inst()->nodeSetData;
	};

	static std::vector<std::string>& GetCellSetName()
	{
		return ReadMesh::Inst()->allElementSetName;
	};

	static std::vector<std::vector<int>>& GetCellSet()
	{
		return ReadMesh::Inst()->elementSetData;
	};

	static std::vector<std::string>& GetSurfaceSetName()
	{
		return ReadMesh::Inst()->allSurfaceSetName;
	};

	/*static std::vector<std::vector<SurfaceElem>>& GetSurfaceSet()
	{
		return ReadMesh::Inst()->surfaceSetData;
	};*/
	//新增代码
	static std::map<std::string, std::vector<std::string>>& GetNodeElementSurfaceSetName()
	{
		return ReadMesh::Inst()->nodeElementSurfaceSetName;
	}
	static std::map<std::string, std::vector<std::string>>& GetDuplicateSetName()
	{
		return ReadMesh::Inst()->duplicateSetName;
	}

	bool destroy_all_data();

	friend AnsysToIBEBuilderModel;
private:
	static ReadMesh* _instance;

	//! for ouput, reference to Interface
	std::vector<int> allNodeId;                           // 包含所有网格点的坐标信息
	std::vector<double> allNodeCoor;                      // 包含所有网格点的坐标信息

	std::vector<int> allElementId;                        // 网格单元id（从1开始）
	std::vector<int> allElmentType;                       // 网格单元类型
	std::vector<int> allElementNode;                      // 组成网格单元的网格点
	std::vector<int> elementIndex;                        // 网格单元位置偏移，第一个为0
	std::vector<std::string> elementFormulation;          // 单元算法

	std::vector<std::string> allNodeSetName;              // 点集合名称
	std::vector<std::vector<int>> nodeSetData;            // 点集合中包含所有的点的id，必须在Node中存在

	std::vector<std::string> allElementSetName;           // 单元集合名称
	std::vector<std::vector<int>> elementSetData;         // 单元集合中所有单元的id，必须在Cell中存在

	std::vector<std::string> allSurfaceSetName;           // 面集合名称
	//std::vector<std::vector<SurfaceElem>> surfaceSetData; // 面集合信息，集合信息包含：集合中每个面的信息（参考SurfaceElem内容）
	//! end ouput
	//新增代码-20240507
	std::map<std::string, std::vector<std::string>> nodeElementSurfaceSetName;//将三类SetName，按类别存储到map中。key是node/element/surface;value是存储各自set名称的容器。
	std::map<std::string, std::vector<std::string>> duplicateSetName;
};
